package com.cskaoyan.order.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.order.biz.TransOutboundInvoker;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.factory.OrderProcessPipelineFactory;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.constant.OrderItemConstants;
import com.cskaoyan.order.constant.OrderRetCode;
import com.cskaoyan.order.converter.OrderConverter;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.OrderShipping;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.OrderShippingMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.*;
import com.cskaoyan.order.form.CreateOrderRequest;
import com.cskaoyan.order.form.OrderListRequest;
import com.cskaoyan.order.service.OrderCoreService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OrderCoreServiceImpl implements OrderCoreService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    OrderConverter orderConverter;

    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public String createOrder(CreateOrderRequest request) {
        //创建pipeline对象
        TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

        //启动pipeline
        invoker.start(); //启动流程（pipeline来处理）

        //获取处理结果
        AbsTransHandlerContext context = invoker.getContext();

        //从Context中获取订单Id
        String orderId = context.getOrderId();
        return orderId;
    }

    /**
     * @param orderId
     * @return ResponseData
     * @description 取消订单
     * URI /shopping/cancelOrder
     * Method post
     * @author silic xia
     * @since 2022/12/04 23:18
     */
    @Override
    public void cancelOrder(String orderId) {
        try {
            // 更新order信息

            updateOrder(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL, orderId);


            // 更新orderItem信息
            updateOrderItemForRollbackStockCount(orderId);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("订单取消异常！");
            throw new BizException(OrderRetCode.CANCEL_ORDER_ERROR.getCode(), OrderRetCode.CANCEL_ORDER_ERROR.getMessage());
        }
    }

    /**
     * @param orderId
     * @return
     * @description 删除订单
     * URI /shopping/order/{id}
     * Method delete
     * @author silic xia
     * @since 2022/12/05 1:28
     */
    @Override
    public void deleteOrder(String orderId) {
        try {
            // 更新order信息

            updateOrder(OrderConstants.ORDER_STATUS_TRANSACTION_DELETED, orderId);


            // 更新orderItem信息
            updateOrderItemForRollbackStockCount(orderId);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("订单删除异常！");
            throw new BizException(OrderRetCode.DELETE_ORDER_ERROR.getCode(), OrderRetCode.DELETE_ORDER_ERROR.getMessage());
        }

    }

    // 整合方法
    private void updateOrderItemForRollbackStockCount(String orderId) {
        List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
        Stock stock = new Stock();
        for (OrderItem orderItem : orderItems) {
            orderItem.setStatus(OrderItemConstants.ORDERITEM_STATUS_RELEASED);
            // 更新库存信息，把lock_count,stock_count更新回去【解锁库存】

            stock.setItemId(Long.valueOf(orderItem.getItemId()));
            stock.setStockCount(orderItem.getNum().longValue());
            stock.setLockCount(-orderItem.getNum());

            if (stock == null) {
                System.out.println("stockMapper异常捕获：SQL异常！数据库异常！");
                throw new BizException(OrderRetCode.DB_EXCEPTION.getCode(),OrderRetCode.DB_EXCEPTION.getMessage());
            }
            stockMapper.updateStock(stock);

        }
    }

    // 整合方法
    @Override
    public void updateOrder(Integer status, String orderId) {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();

        criteria.andEqualTo("orderId", orderId);

        Order order = new Order();
        order.setStatus(status);
        order.setCloseTime(new Date());
        orderMapper.updateByExampleSelective(order, example);
    }

    /**
     * @param
     * @return OrderListResponse
     * @description 获取所有订单
     * @author silic xia
     * @since 2022/12/04 19:23
     */
    @Override
    public OrderListResponse getOrder(OrderListRequest orderListRequest) {


        // 求order个数
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", orderListRequest.getUserId());
        criteria.andNotEqualTo("status", OrderConstants.ORDER_STATUS_TRANSACTION_DELETED);
        List<Order> ordersForNum = orderMapper.selectByExample(example);

        // 求order
        if (orderListRequest.getPage() != null && orderListRequest.getSize() != null){
            PageHelper.startPage(orderListRequest.getPage(), orderListRequest.getSize());
        }
        Example example1 = new Example(Order.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("userId", orderListRequest.getUserId());
        criteria1.andNotEqualTo("status", OrderConstants.ORDER_STATUS_TRANSACTION_DELETED);
        example1.setOrderByClause(OrderConstants.ORDER_SORT_DESC);
        List<Order> orders = orderMapper.selectByExample(example1);

        List<OrderDetailInfo> orderDetailInfos = orderConverter.orderList2detailList(orders);

        // 求orderDetail剩下的信息，并整合到detailInfo
        for (int i = 0; i < orderDetailInfos.size(); i++) {
            OrderDetailInfo orderDetailInfo = orderDetailInfos.get(i);
            String orderId = orderDetailInfo.getOrderId();
            // 求orderItem
            List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
            List<OrderItemDto> orderItemDtos = orderConverter.item2dto(orderItems);
            orderDetailInfo.setOrderItemDto(orderItemDtos);

            // 求orderShipping

            OrderShipping orderShipping = orderShippingMapper.selectByPrimaryKey(orderId);

            OrderShippingDto orderShippingDto = orderConverter.shipping2dto(orderShipping);
            orderDetailInfo.setOrderShippingDto(orderShippingDto);
        }
        PageInfo<OrderDetailInfo> orderDetailInfoPageInfo = new PageInfo<>(orderDetailInfos);
        // 创建传回类
        OrderListResponse orderListResponse = new OrderListResponse();
        orderListResponse.setData(orderDetailInfoPageInfo.getList());

        orderListResponse.setTotal(Long.valueOf(ordersForNum.size()));

        return orderListResponse;
    }

    /**
     * @param orderId
     * @return ResponseData
     * @description 查询订单详情
     * URI shopping/order/{id} 占位符
     * Method get
     * @author silic xia
     * @since 2022/12/04 22:54
     */
    @Override
    public OrderDetailResponse getOrderDetails(String orderId, Long userId) {
        // 创建订单详情响应类
        Order order = orderMapper.selectByPrimaryKey(orderId);

        if (order.getStatus() == OrderConstants.ORDER_STATUS_TRANSACTION_DELETED) {
            throw new BizException(OrderRetCode.CALL_PRODUCT_DETAIL_FAIL.getCode(), OrderRetCode.CALL_PRODUCT_DETAIL_FAIL.getMessage());

        }
        OrderShipping orderShipping = orderShippingMapper.selectByPrimaryKey(orderId);
        OrderDetailResponse orderDetailResponse = orderConverter.order2res(order, orderShipping);

        // 合并响应类
        List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
        List<OrderItemDto> orderItemDtos = orderConverter.item2dto(orderItems);

        orderDetailResponse.setGoodsList(orderItemDtos);
        orderDetailResponse.setUserId(userId);
        return orderDetailResponse;
    }


}
